#include "sched.h"

static void
check_preempt_curr_stop(struct rq *rq, struct tcb *p, int flags)
{
    /* we're never preempted */
}

static struct tcb *pick_next_task_stop(struct rq *rq)
{
    struct tcb *stop = rq->stop;

    if (stop && stop->on_rq) {
        stop->se.exec_start = rq_clock_task(rq);
        return stop;
    }

    return NULL;
}

static void
enqueue_task_stop(struct rq *rq, struct tcb *p, int flags)
{
}

static void
dequeue_task_stop(struct rq *rq, struct tcb *p, int flags)
{
}

static void yield_task_stop(struct rq *rq)
{
    BUG(); /* the stop task should never yield, its pointless. */
}

static void put_prev_task_stop(struct rq *rq, struct tcb *prev)
{
    struct tcb *curr = rq->curr;
    u64 delta_exec;

    delta_exec = rq_clock_task(rq) - curr->se.exec_start;
    if (unlikely((s64)delta_exec < 0))
        delta_exec = 0;

    curr->se.sum_exec_runtime += delta_exec;

    curr->se.exec_start = rq_clock_task(rq);
}

static void task_tick_stop(struct rq *rq, struct tcb *curr, int queued)
{
}

static void set_curr_task_stop(struct rq *rq)
{
    struct tcb *stop = rq->stop;

    stop->se.exec_start = rq_clock_task(rq);
}

static void switched_to_stop(struct rq *rq, struct tcb *p)
{
    BUG(); /* its impossible to change to this class */
}

static void
prio_changed_stop(struct rq *rq, struct tcb *p, int oldprio)
{
    BUG(); /* how!?, what priority? */
}

static unsigned int
get_rr_interval_stop(struct rq *rq, struct tcb *task)
{
    return 0;
}

/*
 * Simple, special scheduling class for the per-CPU stop tasks:
 */
const struct sched_class stop_sched_class = {
    .next				= &dl_sched_class,

    .enqueue_task		= enqueue_task_stop,
    .dequeue_task		= dequeue_task_stop,
    .yield_task			= yield_task_stop,

    .check_preempt_curr	= check_preempt_curr_stop,

    .pick_next_task		= pick_next_task_stop,
    .put_prev_task		= put_prev_task_stop,

    .set_curr_task		= set_curr_task_stop,
    .task_tick			= task_tick_stop,

    .get_rr_interval	= get_rr_interval_stop,

    .prio_changed		= prio_changed_stop,
    .switched_to		= switched_to_stop,
};
